#include "Enemy.h"

Enemy::Enemy(void) : Board(NULL), playerInfo(NULL){
	sightLength = 1.0f;

	rndNum = rand() % 100 + 1;
	
	if(rndNum < 50)
		this->SetDirection(Vector3D(1.0, 0.0, 0.0));
	else
		this->SetDirection(Vector3D(-1.0, 0.0, 0.0));

	enemyDetected = false;
	renderWeapon = false;

	jumpLimit = 0.0f;
	jumpMe = false;

	saveDir = false;

	damage = 1.0f;

	if(invertImage){
		lineOfSight.InitLine(Vector3D(this->GetPosition().x + this->GetWidth(), this->GetPosition().y + this->GetHeight() / 2, this->GetPosition().z)
					, Vector3D(this->GetPosition().x + this->GetWidth() + sightLength, this->GetPosition().y + this->GetHeight() / 2, this->GetPosition().z));
	}else{
		lineOfSight.InitLine(Vector3D(this->GetPosition().x, this->GetPosition().y + this->GetHeight() / 2, this->GetPosition().z)
						, Vector3D(this->GetPosition().x - sightLength, this->GetPosition().y + this->GetHeight() / 2, this->GetPosition().z));
	}
}

Enemy::~Enemy(void){
}

void Enemy::LoadPlayerInfo(Character *player){
	this->playerInfo = player;

	this->TargetInfoList.push_back(playerInfo);
}

void Enemy::LoadTargetInfo(Object *target){
	this->TargetInfoList.push_back(target);
}

void Enemy::LoadMessageBoard(MessageBoard *Board){
	this->Board = Board;
}

void Enemy::SetAttackDamage(float damage){
	this->damage = damage;
}

float Enemy::GetAttackDamage(void){
	return this->damage;
}

void Enemy::SetLengthOfSight(float sightLength){
	this->sightLength = sightLength;
}

void Enemy::WallHit(float elapsed){
	if(!saveDir){
		this->oldDir = this->GetDirection();
		saveDir = true;
	}

	if(this->GetOnGround()){
		this->SetDirection(Vector3D(oldDir.x * -1, oldDir.y, 0.0));
		Object::WallHit(elapsed);
		saveDir = false;
	}else{
		this->SetDirection(Vector3D());
	}
}

void Enemy::Jump(float elapsed){
	if(this->GetOnGround() && !jumpMe){
		jumpMe = true;
		jumpLimit = 90.0f;
	}

	if(jumpMe){
		// Jump
		if ( jumpLimit > 0.0f )
		{
			// Calculate jump
			float temp = this->GetSpeed() * elapsed;

			// Jump up
			this->jumpLimit	-= temp;
			this->SetPosition(Vector3D(this->GetPosition().x, this->GetPosition().y - temp - GRAVITY, this->GetPosition().z));
			
			// End jump
			if ( jumpLimit < 0.0f )
			{
				this->SetPosition(Vector3D(this->GetPosition().x, this->GetPosition().y - jumpLimit, this->GetPosition().z));
				this->jumpLimit	= 0.0f;
				jumpMe = false;
			}
		}
	}
}

void Enemy::RenderObject(void){
	Object::RenderObject();

	if(renderWeapon)
		weapon.RenderObject();

	//lineOfSight.DrawLine();

	//spaceCheck.DrawBox();
}

void Enemy::CreatePickUp(Vector3D position, Item::no itemNumber, vector<PickUp *> *PickUpList){
	PickUp *newPickUp = new PickUp;
	newPickUp->InitPickUp( position, itemNumber );
	newPickUp->SetOnGround(true);
	(*PickUpList).push_back( newPickUp );
}

bool Enemy::UpdateObject(Vector3D offset, float elapsed){
	Object::UpdateObject(offset, elapsed);

	if(countdownTimer.CheckIfTimerRunning())
		countdownTimer.UpdateTimer();

	if(this->GetDirection().x == 1){
		this->invertImage = true;
		//this->MoveMeLeftRight(true, elapsed);
		this->PlaySpriteAnimation(5, 8, 500);
	}else if(this->GetDirection().x == -1){
		this->invertImage = false;
		//this->MoveMeLeftRight(false, elapsed);
		this->PlaySpriteAnimation(5, 8, 500);
	}

	this->SetPosition(this->GetPosition() + this->GetDirection() * this->GetSpeed() * elapsed);

	for(vector<Object *>::iterator itr = TargetInfoList.begin(); itr != TargetInfoList.end(); ++itr){
		if(this->lineOfSight.HitTest((*itr)->GetBoundingBox(Object::FULLBODY))){
			enemyDetected = true;
			break;
		}else{
			enemyDetected = false;
		}
	}

	/*if(this->lineOfSight.HitTest(playerInfo->GetBoundingBox(Object::FULLBODY))){
		enemyDetected = true;
		targetAttack = false;
	}else if(extraTarget){
		if(this->lineOfSight.HitTest(target->GetBoundingBox(Object::FULLBODY))){
			enemyDetected = true;
			targetAttack = true;
		}else{
			targetAttack = false;
		}
	}else{
		enemyDetected = false;
	}*/

	if(playerInfo->Get_Character_Weapon()->GetBoundingBox(Object::FULLBODY).HitTest(this->GetBoundingBox(Object::FULLBODY)) 
		&& playerInfo->Get_Character_Weapon()->CheckIfAttacking()){
			if(!defendTime)
				this->ReduceLife(playerInfo->Get_Character_Weapon()->GetAttackDamageAttack());
			else
				this->ReduceLife((playerInfo->Get_Character_Weapon()->GetAttackDamageAttack() / 2));
	}

	if(invertImage){
		lineOfSight.InitLine(Vector3D(this->GetPosition().x + this->GetWidth(), this->GetPosition().y + this->GetHeight() / 2, this->GetPosition().z)
					, Vector3D(this->GetPosition().x + this->GetWidth() + sightLength, this->GetPosition().y + this->GetHeight() / 2, this->GetPosition().z));

		weapon.SetPosition(Vector3D(this->GetPosition().x + this->GetWidth(), this->GetPosition().y, this->GetPosition().z));

		spaceCheck.SetPosition(Vector3D(this->GetPosition().x + this->GetWidth(), this->GetPosition().y + spaceCheck.GetHeight(), this->GetPosition().z));
	}else{
		lineOfSight.InitLine(Vector3D(this->GetPosition().x, this->GetPosition().y + this->GetHeight() / 2, this->GetPosition().z)
						, Vector3D(this->GetPosition().x - sightLength, this->GetPosition().y + this->GetHeight() / 2, this->GetPosition().z));

		weapon.SetPosition(Vector3D(this->GetPosition().x - weapon.GetWidth(), this->GetPosition().y, this->GetPosition().z));

		spaceCheck.SetPosition(Vector3D(this->GetPosition().x, this->GetPosition().y + spaceCheck.GetHeight(), this->GetPosition().z));
	}

	return false;
}